﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;
using System.Threading;

using SpotItComponents;
using SpotItServerAPI;

using Vitruvian.Serialization;
using Vitruvian.Services;
using Vitruvian.Testing;
using Vitruvian.Logging;

namespace SpotItServerTester
{
    [ContainsTests("SystemTest.SymbolManagement")]
    public class SymbolManagerTester : BaseTester
    {
        public SymbolManagerTester() { }

        [OneTimeSetup]
        public void TestSuiteSetup()
        {
            base.EstablishConnectionToServer();

            base.WaitForAllDistributedServices();
            Assert.IsNotNull(accountManager);
            Assert.IsNotNull(symbolManager);

            base.LoginInAsAdmin();
            Assert.IsNotNull(mySession);
            Assert.IsTrue(mySession.UserInfo.IsAdmin);

            // Remove all existing symbol sets
            OperationResult result = symbolManager.RemoveAllSymbolSets(mySession);
            Assert.IsTrue(result.Success);
        }


        [Test(1)]
        public void Test_SymbolSet_BasicOperations()
        {
            // Get the current full list of system sets
            OperationResult result = symbolManager.Lookup(mySession, null, null, null);
            Assert.IsTrue(result.Success);
            List<SymbolSet> origSystemSets = result.Data as List<SymbolSet>;
            Assert.IsNotNull(origSystemSets);

            // CASE 1 - Add a simple symbol set
            // Create a symbol set locally, and then add it to the server via the symbol manager
            SymbolSet ss1 = new SymbolSet("My Favorite Symbols", true);

            ss1.AddSymbol(Symbol.CreateSymbolWithLabelImage("Alligator", new Bitmap("../../../Symbols/Alligator.jpg")));
            ss1.AddSymbol(Symbol.CreateSymbolWithLabelImage("Crab", new Bitmap("../../../Symbols/Crab.jpg")));
            ss1.AddSymbol(Symbol.CreateSymbolWithLabelImage("Dolphin", new Bitmap("../../../Symbols/Dolphin.jpg")));
            Assert.IsEqual(3, ss1.Symbols.Count);

            ss1.AddCategory(new Category("Test Category A"));
            ss1.AddCategory(new Category("Test Category B"));
            Assert.IsEqual(2, ss1.Categories.Count);

            // Add the symbol set to the server via the symbol manager
            result = symbolManager.Add(mySession, ss1);
            Assert.IsTrue(result.Success);

            // Then make sure it is there by getting the new full list of system sets and seeing if the new set
            // is in that list
            result = symbolManager.Lookup(mySession, null, null, null);
            Assert.IsTrue(result.Success);
            List<SymbolSet> newSystemSets = result.Data as List<SymbolSet>;
            Assert.IsNotNull(newSystemSets);
            Assert.IsEqual(origSystemSets.Count + 1, newSystemSets.Count);
            Assert.IsTrue(newSystemSets.Contains(ss1));

            // CASE 2 - Add a copy of symbol set
            SymbolSet ss2 = new SymbolSet(ss1, false);
            ss2.Label = "Copy of My Favorite Symbols";
            result = symbolManager.Add(mySession, ss2);
            Assert.IsTrue(result.Success);

            result = symbolManager.Lookup(mySession, null, null, null);
            Assert.IsTrue(result.Success);
            newSystemSets = result.Data as List<SymbolSet>;
            Assert.IsNotNull(newSystemSets);
            Assert.IsEqual(origSystemSets.Count + 2, newSystemSets.Count);
            Assert.IsTrue(newSystemSets.Contains(ss2));

            // CASE 3 - Add another copy of symbol set
            SymbolSet ss3 = new SymbolSet(ss1, false);
            ss3.Label = "Another Copy of My Favorite Symbols";
            result = symbolManager.Add(mySession, ss3);
            Assert.IsTrue(result.Success);

            result = symbolManager.Lookup(mySession, null, null, null);
            Assert.IsTrue(result.Success);
            newSystemSets = result.Data as List<SymbolSet>;
            Assert.IsNotNull(newSystemSets);
            Assert.IsEqual(origSystemSets.Count + 3, newSystemSets.Count);
            Assert.IsTrue(newSystemSets.Contains(ss3));

            // CASE 4 - Try to add an null
            result = symbolManager.Add(mySession, null);
            Assert.IsFalse(result.Success);

            // CASE 5 - Remove ss2
            result = symbolManager.Remove(mySession, ss2);
            Assert.IsTrue(result.Success);
            result = symbolManager.Lookup(mySession, null, null, null);
            Assert.IsTrue(result.Success);
            newSystemSets = result.Data as List<SymbolSet>;
            Assert.IsNotNull(newSystemSets);
            Assert.IsEqual(origSystemSets.Count + 2, newSystemSets.Count);
            Assert.IsFalse(newSystemSets.Contains(ss2));

            // CASE 6 - Update ss1
            ss1.AddSymbol(Symbol.CreateSymbolWithLabelImage("Another Crab", new Bitmap("../../../Symbols/Crab.jpg")));
            ss1.AddCategory(new Category("Test Category C"));
            result = symbolManager.Update(mySession, ss1);
            Assert.IsTrue(result.Success);

            // CASE 7 - Lookup ss1 from the Server
            result = symbolManager.Lookup(mySession, ss1.Id);
            Assert.IsTrue(result.Success);
            SymbolSet ss1a = result.Data as SymbolSet;
            Assert.IsEqual(ss1.Id, ss1a.Id);
            Assert.IsEqual(ss1.Label, ss1a.Label);
            Assert.IsEqual(ss1.Symbols.Count, ss1a.Symbols.Count);
            Assert.IsEqual(ss1.Categories.Count, ss1a.Categories.Count);

            // CASE 8 - Try to update an non-existing symbol set
            result = symbolManager.Update(mySession, ss2);
            Assert.IsFalse(result.Success);
        }

        [Test(5)]
        public void Test_SymbolSet_ChangeOwner()
        {
            // TODO:
        }

        [Test(6)]
        public void Test_SymbSet_RemoveAllSymbolSets()
        {
            // TODO:
        }

    }
}
